package Agent;

import java.util.Vector;

import Env.Car;
import Env.Environment;
import Main.*;

/**
 * TODO Put here a description of what this class does.
 *
 * @author danny.
 *         Created 15 ���� 2011.
 */
public abstract class AbstractAgent {
	/**
	 * TODO Put here a description of this field.
	 */
	protected int position;
	protected int goal;
	protected Environment env;
	protected Vector<Integer> history;
	private float timeSpent;
	private static int IDGIVER=1;
	private int id;
	protected boolean stopFlag;
	protected String agentName;
	
	//Used only by choose()
	protected Car chosenCar;
	protected int chosenVertex;
	
	public boolean getStopFlag(){
		return stopFlag;
	}
	
	public AbstractAgent(int start,int goal,Environment env){
		this.position = start;
		this.goal=goal;
		this.env=env;
		history= new Vector<Integer>();
		timeSpent=0;
		id=IDGIVER;
		IDGIVER++;
		Main.log.fine("agent "+id+" created");
		stopFlag=false;
	}
	
	protected abstract void chooseCarAndVertex() throws Exception;
	
	
	public void move() throws Exception{
		if (!stopFlag){
			chooseCarAndVertex();
			if (chosenCar!=null && chosenVertex!=-1){
				if (!legalMove())
					throw new Exception ("move is not legal");
				history.add(position);
				try {
					int oldVertex = position;
					timeSpent+=env.drive(this.position,chosenVertex,chosenCar);
				//	System.out.println("agent " + agentName + " drove from v" + oldVertex + " to v" + chosenVertex + " with car " + chosenCar);
				} catch (Exception exception) {
					Main.log.severe("exception happened agent "+ id);
					exception.printStackTrace();
				}
				this.position=chosenVertex;
				Main.log.fine("agent "+id+" has moved from "+this.history.lastElement() + " to "+position+ " and his time is now "+timeSpent);
			}else{
				Main.log.fine("agent "+id+" tried to move but failed");
			}
			System.out.println("moved to vertex " + chosenVertex + " with car " + chosenCar);

			
		}
	}

	/**
	 * TODO Put here a description of what this method does.
	 *
	 * @return
	 * @throws Exception 
	 */
	private boolean legalMove() throws Exception {
		if (env.getGraph().isEdgeFlooded(position,chosenVertex) && chosenCar.getEff()==0) return false;
		return true;
	}

}
